package cc.rengu.redp.bizimpl.upmp.controller;

import cc.rengu.redp.bizimpl.enums.PageOptFlagEnum;
import cc.rengu.redp.bizimpl.enums.ValidatMethodEnum;
import cc.rengu.redp.bizimpl.upmp.domain.BTermBrandInfo;
import cc.rengu.redp.bizimpl.upmp.service.IBTermBrandInfoService;
import cc.rengu.redp.bizimpl.upmp.vo.BTermBrandInfoVO;
import cc.rengu.redp.bizimpl.utils.StringValicationUtil;
import cc.rengu.redp.common.annotation.Log;
import cc.rengu.redp.common.controller.BaseController;
import cc.rengu.redp.common.domain.QueryRequest;
import cc.rengu.redp.common.domain.RedpResponse;
import cc.rengu.redp.common.exception.RedpException;
import cc.rengu.redp.common.utils.EasyExcelUtil;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.wuwenze.poi.ExcelKit;
import com.wuwenze.poi.handler.ExcelReadHandler;
import com.wuwenze.poi.pojo.ExcelErrorField;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.IntStream;

/**
 * @author lizk
 */
@Slf4j
@RestController
@RequestMapping("terminalAdmin")
public class BTermBrandInfoController extends BaseController {

    @Autowired
    private IBTermBrandInfoService bTermBrandInfoService;

    @GetMapping
    public Map<String, Object> brandList(QueryRequest queryRequest, BTermBrandInfo brand) {
        return getDataTable(bTermBrandInfoService.findByPage(queryRequest, brand));
    }

    @GetMapping("getBrandCode")
    public List<BTermBrandInfo> getBrandCode(@RequestParam("instId") String instId) {
        return bTermBrandInfoService.getBrandCode(instId);
    }

    @GetMapping("termbrandSelect2List")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "q", value = "参数", required = true, dataType = "String")
    })
    public Map<String, Object> termbrandSelect2List(String q, QueryRequest request){
        return bTermBrandInfoService.termbrandSelect2List(q, request);
    }

    /**
     * 查品牌名称
     *
     * @param brandCode
     * @return
     */
    @GetMapping("getByBrandCode")
    public BTermBrandInfo getBrandCodeAndName(@RequestParam("brandCode") String brandCode) {
        return bTermBrandInfoService.getBrandCodeAndName(brandCode);
    }

    @Log("新增品牌")
    @PostMapping
//    @RequiresPermissions("brand:add")
    public void addBrand(@Valid BTermBrandInfoVO brand) throws RedpException {

        if (PageOptFlagEnum.OPT_FLAG_CHECK.getType().equals(brand.getFlag())) {
            try {
                this.bTermBrandInfoService.createBrand(brand);
            } catch (Exception e) {
                String message = e.getMessage();
                log.error(message, e);
                throw new RedpException(message);
            }
        } else {

            char c = brand.getBrandName().charAt(0);
            //商户、终端的导出模板使用HSSFName设置别名时有限制，参考HSSFName.validateName
            if (c != '_' && !Character.isLetter(c) || brand.getBrandName().indexOf(32) != -1) {
                String message = "终端品牌名首字符必须是汉字或字母";
                log.error(message);
                throw new RedpException(message);
//                return OperationResult.buildFailureResult("终端品牌名首字符必须是汉字或字母", result);
            }
            try {
                this.bTermBrandInfoService.createBrand(brand);
            } catch (Exception e) {
                String message = e.getMessage();
                log.error(message, e);
                throw new RedpException(message);
            }
        }
    }


    @Log("修改品牌")
    @PutMapping
//    @RequiresPermissions("brand:update")
    public void updateBland(BTermBrandInfoVO brand) throws RedpException {
        try {
            this.bTermBrandInfoService.updateBrand(brand);
        } catch (Exception e) {
            String message = e.getMessage();
            log.error(message, e);
            throw new RedpException(message);
        }
    }

    /**
     * 生成 Excel导入模板
     */
    @PostMapping("downloadTemplate")
    public void generateImportTemplate(HttpServletResponse response) throws IOException {
        // 构建数据OrgChargeReportController
        List<BTermBrandInfoVO> list = new ArrayList<>();
        IntStream.range(0, 1).forEach(i -> {
            BTermBrandInfoVO brandInfoVO = new BTermBrandInfoVO();
            brandInfoVO.setBrandName("牛");
            brandInfoVO.setBrandDesc("好品牌");
            brandInfoVO.setContactName("upmp" + i + "@gmail.com");
            brandInfoVO.setContactPhone("13800138000");
            brandInfoVO.setContactEmail("upmp" + i + "@gmail.com");
            list.add(brandInfoVO);
        });
        // 构建模板
        EasyExcelUtil.export(response, list, "终端品牌导入模板");
    }


    /**
     * 导入Excel数据，并批量插入 T_B_TERM_BRAND_INFO表
     */
    @PostMapping("import")
    public RedpResponse importExcels(@RequestParam("file") MultipartFile file, @RequestParam("instId") String instId) throws RedpException {
        try {
            if (file.isEmpty()) {
                throw new RedpException("导入数据为空");
            }
            String filename = file.getOriginalFilename();
            if (!StringUtils.endsWith(filename, ".xlsx")) {
                throw new RedpException("只支持.xlsx类型文件导入");
            }
            // 开始导入操作
            long beginTimeMillis = System.currentTimeMillis();
            final List<BTermBrandInfoVO> data = Lists.newArrayList();
            final List<Map<String, Object>> error = Lists.newArrayList();
            ExcelKit.$Import(BTermBrandInfoVO.class).readXlsx(file.getInputStream(), new ExcelReadHandler<BTermBrandInfoVO>() {
                @Override
                public void onSuccess(int sheet, int row, BTermBrandInfoVO test) {
                    //先判断品牌名称存不存在
                    boolean result = bTermBrandInfoService.count(test.getBrandName());
                    List<ExcelErrorField> list = new ArrayList<>();
                    if (result) {//不存在
                        String contactPhonevali = StringValicationUtil.validate(ValidatMethodEnum.CHECK_PHONE,test.getContactPhone());
                        //判断手机号格式是否正确
                        if(StringUtils.isNotBlank(contactPhonevali)) {
                            //不正确
                            list.add(new ExcelErrorField(0, test.getContactPhone(), "联系人电话", "手机号或座机号格式不正确"));
                            error.add(ImmutableMap.of("row", row, "errorFields", list));
                        }else {
                            //不存在且手机号格式正确，加入集合
                            test.setCreatTime(new Date());
                            test.setInstId(instId);
                            data.add(test);
                        }
                    } else {
                        //把品牌名称重复的放置到错误信息里面
                        list.add(new ExcelErrorField(0, test.getBrandName(), "品牌名称", "品牌名称重复，请修改再试"));
                        error.add(ImmutableMap.of("row", row, "errorFields", list));
                    }

                }

                @Override
                public void onError(int sheet, int row, List<ExcelErrorField> errorFields) {
                    // 数据校验失败时，记录到 error集合
                    error.add(ImmutableMap.of("row", row, "errorFields", errorFields));
                }
            });
            if (!data.isEmpty()) {
                // 将合法的记录批量入库
                this.bTermBrandInfoService.batchInsert(data);
            }
            long time = ((System.currentTimeMillis() - beginTimeMillis));
            ImmutableMap<String, Object> result = ImmutableMap.of(
                    "time", time,
                    "data", data,
                    "error", error
            );
            return new RedpResponse().data(result);
        } catch (Exception e) {
            String message = "导入Excel数据失败," + e.getMessage();
            log.error(message);
            throw new RedpException(message);
        }
    }

}
